/*
 * ota_updater.cpp
 *
 *  Created on: 2016-7-15
 *      Author: duanlian01
 */
#include "k64f_ota_updater.h"
#include "baidu_iot_ota_log.h"
#include "FreescaleIAP.h"
#include "flash.h"

const unsigned int PAGE_SIZE = 1024;
char cache[PAGE_SIZE];
unsigned int left_size = 0;
unsigned int last_addr = 0;

int k64f_notify_data_begin()
{
	  OTA_FUNC_ENTER();
	  //flash_unlock();
	  memset(cache, 0xff, PAGE_SIZE);
	  left_size = 0;
	  last_addr = 0;
	  OTA_FUNC_LEAVE();
    return 0;
}

int k64f_notify_meta_data(void *cxt, struct package_meta_data *meta){
	struct k64f_ota_update_context *context = (struct k64f_ota_update_context*)cxt;
	OTA_FUNC_ENTER();
	if (context && meta && meta->install_info.module_count > 0)
	{
	    context->info = meta->install_info.module_list[0];
		  const int upgrade_start_address = 0x90000;
		  const int upgrade_max_size = 0x50000;
		  flash_erase(upgrade_start_address, upgrade_max_size);
		  context->address =  upgrade_start_address;   //write start position 
          last_addr = upgrade_start_address;
	}
	OTA_FUNC_LEAVE();
	return 0;
}

int k64f_notify_module_data(void *cxt, unsigned int offset, unsigned char *data, unsigned int size)
{
	OTA_FUNC_ENTER();
	struct k64f_ota_update_context *context = (struct k64f_ota_update_context*)cxt;
	if (context)
	{
		  
		  if ((left_size + size) < PAGE_SIZE)
			{
			    OTA_LOG_INFO("cache %d bytes from 0x%8x\n", size, (context->address + offset));
			    memcpy(cache + left_size, data, size);
				  left_size += size;
				  data += size;
				  size = 0;
			}
			else
			{
			    unsigned int copy = PAGE_SIZE - left_size;
				  memcpy(cache + left_size, data, copy);
				  IAPCode status = 0;
				  
				  status = program_flash(last_addr, cache, PAGE_SIZE);
		          OTA_LOG_INFO("%d bytes written from 0x%8x, result:%d\n", PAGE_SIZE, last_addr,(int)status);
                  last_addr += PAGE_SIZE;
				  
				  memcpy(cache, data + copy, size - copy);
				  left_size = size - copy;
				  data += size;
				  size = 0;
			}
	}
	OTA_FUNC_LEAVE();
	return 0;
}

int k64f_notify_data_end()
{
	  //flash_lock();
	OTA_FUNC_ENTER();
	IAPCode status = 0;
				  
	status = program_flash(last_addr, cache, left_size);
	OTA_LOG_INFO("%d bytes written from 0x%8x, result:%d\n", left_size, last_addr,(int)status);
    OTA_FUNC_LEAVE();
	return 0;
}

int k64f_ota_update_image_begin()
{
    return 0;
}

static void k64f_ota_restart()
{
}

int k64f_ota_update_image()
{
	OTA_FUNC_ENTER();
	//calculate crc, if something wrong happens, erase the content just written
	OTA_FUNC_LEAVE();
	return 0;
}

int k64f_ota_update_image_end()
{
	  k64f_ota_restart();
    return 0;
}
